package com.eugenema.demand.impl;

import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.eugenema.demand.Demand;
import com.eugenema.util.Annotation.DemandBean;
import com.eugenema.util.DemandUtil.LeagueMatchUtil;
import com.eugenema.util.ExcelUtil.ExcelConfigFactory;
import com.eugenema.util.SeleniumUtil;
import com.jfoenix.controls.JFXButton;
import javafx.scene.control.Tooltip;
import org.kordamp.ikonli.javafx.FontIcon;

import java.util.*;
/**
 * <p>标题：F5 红宝书</p>
 * <p>
 *  功能：获取指定联赛所有球队最近 30 场连续 3 场及以上单双数的数据
 * </p>
 * <p>其他说明：存入全局存储中的 key 为方法名，即 demandTwo</p>
 * <p>作者：马寅广</p>
 * <p>审核：</p>
 * <p>重构：</p>
 * <p>创建日期：2024/1/1 10:27</p>
 */
@DemandBean(key = DemandF5RedGemBook.DEMAND_TWO_PARAMETER_KEY, title = "F5 红宝书", notice = "获取指定联赛所有球队最近 30 场连续 3 场及以上单双数的数据", order = 3)
public class DemandF5RedGemBook extends Demand {
    /** 需求二要抓数的指定联赛 key */
    public static final String DEMAND_TWO_PARAMETER_KEY = "league_two";
    /** 需求二映射后的实体列表 */
    private List<List<String>> evenMatchDataList = new ArrayList<>();
    /** 需求二行格式 */
    private ArrayList<WriteCellStyle> writeCellStyles = new ArrayList<>();
    //获取统计联赛信息的偏移量，代表统计信息从何处开始统计
    private int offset;

    /**
     * 需求方法体
     * <br/> 需求执行的具体逻辑
     *
     * @return 执行结果
     * @author 马寅广
     * @date 2023/12/31 20:52
     **/
    @Override
    public boolean execute() {
        try {
            //进入指定联赛界面，并遍历所有球队
            LeagueMatchUtil.leagueToTeam(RunSeleniumService(), DEMAND_TWO_PARAMETER_KEY,
                    (leagueName) -> {
                        // 获取当前统计联赛信息的偏移量，确保新的统计数据从当前联赛开始，用来处理多个联赛时的情况
                        offset = evenMatchDataList.size();
                        //对需求二导出的数据增加联赛名称，并设置行格式
                        evenMatchDataList.add(Arrays.asList(leagueName));
                        writeCellStyles.add(ExcelConfigFactory.getTitleCellStyle());
                    },
                    (sinOrDouList, teamEntry) -> {
                        /** 单双数量 */
                        int sinOrDou = 1;
                        /** 球队连场数据 */
                        List<String> evenMatchData = new ArrayList<>();
                        evenMatchData.add(teamEntry.getKey());

                        //获取所有连场 ≥ 3 的连场数
                        for (int j = 0; j < sinOrDouList.size() - 1; j++) {
                            if (sinOrDouList.get(j).equals(sinOrDouList.get(j + 1))) {
                                sinOrDou++;
                            } else {
                                //记录连场数 ≥ 3 的记录，排除头尾不确定的连场
                                if (sinOrDou >= 3 && j != sinOrDou - 1) {
                                    evenMatchData.add(String.valueOf(sinOrDou));
                                }
                                sinOrDou = 1;
                            }
                        }
                        //添加该条记录
                        evenMatchDataList.add(evenMatchData);
                        //设置需求二的行样式
                        writeCellStyles.add(ExcelConfigFactory.getCenterCellStyle());
                    },
                    // 插入统计信息
                    this::generateTotalData
            );
        } catch (Exception e) {
            Logger().error("执行异常：", e);
            if (evenMatchDataList.isEmpty()) {
                Logger().error("处理数据为空，本次将不导出数据！");
                return false;
            } else {
                Logger().error("正在将已处理数据导出……");
            }
        }

        //将处理好的数据，以及样式存入全局存储 map（Selenium.globalMap）
        SeleniumUtil.globalMap.put("demandTwo", evenMatchDataList);
        SeleniumUtil.globalMap.put("demandTwoStyle", writeCellStyles);

        //将获取到的所有球队的未来最近一次比赛数据输出至 Excel
        RunSeleniumService().runStep("step_8");
        return true;
    }

    /**
     * 初始化按钮
     *
     * @author 马寅广
     * @date 2023/12/31 19:30
     **/
    @Override
    public void initButton() {
        createEditParameterButton();
        createOpenFileButton("F5红宝书.xlsx");
    }

    /**
     * 插入统计信息
     *
     * @param leagueName 联赛名
     * @author Eugenema
     * @date 2023/5/16 22:24
     **/
    private void generateTotalData(String leagueName) {
        //向数据中添加空行，分割球队连场数据与连场统计数据
        evenMatchDataList.add(null);
        writeCellStyles.add(null);
        evenMatchDataList.add(null);
        writeCellStyles.add(null);
        //统计连场数据
        Map<Integer, Integer> evenMatchStatistics = new TreeMap<>();
        for (int i = offset; i < evenMatchDataList.size(); i++) {
            List<String> rowData = evenMatchDataList.get(i);
            if (rowData == null) {
                continue;
            }
            // 遍历每行数据，跳过第一列
            for (int i1 = 1; i1 < rowData.size(); i1++) {
                try {
                    String cellData = rowData.get(i1);
                    int evenMatch = Integer.valueOf(cellData);
                    Integer value = evenMatchStatistics.get(evenMatch);
                    if (value != null) {
                        evenMatchStatistics.put(evenMatch, ++value);
                    } else {
                        evenMatchStatistics.put(evenMatch, 1);
                    }
                } catch (Exception e) {
                    Logger().error("统计连场数据时发生错误", e);
                }
            }
        }

        //填充数据
        /** 统计所有连场总数，从 3 连开始到 15 连 */
        int total = 0;
        /** 连场标题行 */
        ArrayList<String> rowTitle = new ArrayList<>();
        rowTitle.add(null);
        for (int i = 3; i < 16; i++) {
            rowTitle.add(i + "连");
        }
        rowTitle.add("小计");
        evenMatchDataList.add(rowTitle);
        writeCellStyles.add(ExcelConfigFactory.getCenterCellStyle());

        /** 连场数据行 */
        ArrayList<String> rowData = new ArrayList<>();
        rowData.add(leagueName);
        for (int i = 3; i < 16; i++) {
            Integer value = evenMatchStatistics.get(i);
            rowData.add(value != null ? String.valueOf(value) : null);
            if (value != null) {
                total += value;
            }
        }
        rowData.add(String.valueOf(total));
        evenMatchDataList.add(rowData);
        writeCellStyles.add(ExcelConfigFactory.getCenterCellStyle());

        //向数据中添加空行，分割两个联赛
        evenMatchDataList.add(null);
        writeCellStyles.add(null);
        evenMatchDataList.add(null);
        writeCellStyles.add(null);
    }

    /**
     * 生成编辑参数按钮
     *
     * @author 马寅广
     * @date 2024/1/1 12:06
     *
     **/
    public void createEditParameterButton() {
        JFXButton button = new JFXButton();
        button.getStyleClass().add("radiuButton");
        // 图标
        FontIcon fontIcon = new FontIcon();
        fontIcon.setIconLiteral("fi-pencil");
        fontIcon.setIconSize(20);
        fontIcon.getStyleClass().add("button-icon");
        button.setGraphic(fontIcon);
        // 提示信息
        button.setTooltip(new Tooltip("编辑参数"));
        // 附属信息
        button.setUserData("demandOne");
        // 点击事件，绑定控制器提供的方法
        button.setId("editParameter_demandOne");
        addButton(button);
    }

    /**
     * 生成打开文件按钮
     *
     * @author 马寅广
     * @date 2024/1/1 12:05
     *
     **/
    public void createOpenFileButton() {
        JFXButton button = new JFXButton();
        button.getStyleClass().add("radiuButton");
        // 图标
        FontIcon fontIcon = new FontIcon();
        fontIcon.setIconLiteral("fi-page-csv");
        fontIcon.setIconSize(20);
        fontIcon.getStyleClass().add("button-icon");
        button.setGraphic(fontIcon);
        // 提示信息
        button.setTooltip(new Tooltip("打开生成的文件"));
        // 附属信息
        button.setOnAction(action -> openFile("F5赛程.xlsx"));
        addButton(button);
    }
}
